import 'dart:math';
import 'dart:ui';

import 'package:flutter/material.dart';

import '../utils/color_utils.dart';
import 'base/base_effect.dart';
import 'effect_template.dart';

class Effect10 extends EditableAnimationEffect {
  @override
  List<Color> get defaultColors {
    return const [
      Color(0xFFFFFF00),
      Color(0xFF00FF00),
      Color(0xFF00FFFF),
      Color(0xFF0000FF),
      Color(0xFFFF00FF)
    ];
  }

  @override
  bool get enableAngle => false;

  @override
  bool get enableColorWidth => false;

  @override
  bool get enableDensity => false;

  @override
  bool get enableEditColor => true;

  @override
  bool get enableSpeed => false;

  @override
  bool get isFixedColorCount => false;

  @override
  RangeArgument get colorCountRange => RangeArgument(1,6,4);

  @override
  EffectType get effectTyp => EffectType.effect10;

  @override
  Future<List<List<List<Color>>>> getFrames({EffectOperation? operation}) {
    int sizeWidth = size.width.toInt();
    int sizeHeight = size.height.toInt();
    final colorList = getColorList(effectOperation: operation);

    ///渐变色宽度
    int colorWidth = 9;
    int distance = 6;
    ///每种颜色帧数为mapping宽度一半
    int singleColorFrameCount = (colorWidth + distance)*2;

    List<double> stops = [0,4,5,9];
    List<double> changeStops = [0,singleColorFrameCount.toDouble()];
    int totalFrame = colorList.length * singleColorFrameCount;
    ///初始化上一个颜色为列表最后一个颜色
    int lastColorIndex = 0;
    List<List<List<Color>>> frames = [];
    int currentColorIndex = 0;
    for(int i = 0;i< totalFrame;i++){
      List<List<Color>> frame = [];
      int remainIndex = i%singleColorFrameCount;
      if(remainIndex == 0){
        lastColorIndex = currentColorIndex;
        if(currentColorIndex == colorList.length -1){
          currentColorIndex = 0;
        }else{
          currentColorIndex++;
        }
      }
      Color currentColor = colorList[currentColorIndex];
      Color lastColor = colorList[lastColorIndex];
      Color gradientColor = ColorUtils.lerpGradient([lastColor,currentColor], changeStops, remainIndex.toDouble());
      for(int j = 0;j< sizeWidth;j++){
        int index = totalFrame - i + j;
        int widthIndex = index%(colorWidth+distance);
        Color columnColor;
        if(widthIndex<=colorWidth){
          List<Color> gradientColorList = [
            Color(0xFF000000),
            gradientColor,
            gradientColor,
            Color(0xFF000000)
          ];
          columnColor = ColorUtils.lerpGradient(gradientColorList, stops, widthIndex.toDouble());
        }else{
          columnColor = Color(0xFF000000);
        }
        List<Color> columns = List.generate(sizeHeight, (index) => columnColor);
        frame.add(columns);
      }

      int count = Random().nextInt(6);
      for(int h = 0;h<count;h++){
        int x = Random().nextInt(size.width.toInt());
        int y = Random().nextInt(size.height.toInt());
        int alpha = Random().nextInt(255);
        frame[x][y] = Colors.white.withAlpha(alpha);
      }
      frames.add(frame);
    }
    return Future.value(frames);
  }

  @override
  Size get size => const Size(24, 24);
}